package com.runfast.waimai.service.impl;

import com.runfast.common.dao.model.RunfastCuseraddress;
import com.runfast.common.dao.model.RunfastDeliverCost;
import com.runfast.common.exception.BaseException;
import com.runfast.common.service.RunfastCuseraddressService;
import com.runfast.common.service.RunfastDeliverCostService;
import com.runfast.common.utils.GeoUtil;
import com.runfast.common.web.entity.Result;
import com.runfast.common.web.entity.ResultCode;
import com.runfast.waimai.common.Constants;
import com.runfast.waimai.dao.model.*;
import com.runfast.waimai.entity.*;
import com.runfast.waimai.service.*;
import com.runfast.waimai.web.dto.BusinessDto;
import com.runfast.waimai.web.dto.RedPacketRecordWithOneRedActivityDto;
import com.runfast.waimai.web.dto.TargetWithOneActivityDto;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author: lijin
 * @date: 2018年05月17日
 */
@Service
public class CartServiceImpl implements CartService {
    @Resource
    private RedisTemplate redisTemplate;

    @Autowired
    private RunfastShoppingtrolleyService shoppingtrolleyService;

    @Autowired
    private RunfastGoodsSellStandardService standardService;

    @Autowired
    private RunfastGoodsSellOptionService optionService;

    @Autowired
    private RunfastGoodsSellSubOptionService subOptionService;

    @Autowired
    private RunfastGoodsSellService goodsSellService;

    @Autowired
    private RunfastActivityService activityService;

    @Autowired
    private RunfastActivityTargetService activityTargetService;

    @Autowired
    private RunfastBusinessService businessService;

    @Autowired
    private RunfastFullLessService fullLessService;


    @Autowired
    private RunfastGoodsSellRecordService orderService;

    @Autowired
    private RunfastGoodsSellChildrenService orderItemService;


    @Autowired
    private CartService cartService;

    @Autowired
    private RunfastDeliverCostService deliverCostService;

    @Autowired
    private RunfastCuseraddressService cuseraddressService;

    @Autowired
    private RunfastRedPacketRecordService redPacketRecordService;

    @Autowired
    private RunfastGoodsSellChildrenService goodsSellChildrenService;

    /**
     * 校验购物车参数
     *
     * @param businessId
     * @param cart
     * @param checked    true只校验选择的购物车商品，否则校验所有
     * @return
     */
    @Override
    public Map<String, List<Map<String, Object>>> checkCart(Integer businessId, List<CartItem> cart, boolean check) {
        /**
         * 校验null
         */
        Validate.notNull(businessId);

        if (cart == null || cart.isEmpty()) throw new BaseException(ResultCode.FAIL, "购物车为空");

        if (check) {
            Boolean checkedExist = false;
            for (CartItem cartItem : cart) {
                if (cartItem.getChecked() == true) checkedExist = true;
            }
            if (!checkedExist) throw new BaseException(ResultCode.FAIL, "请选择要下单的商品");
        }


        List<CartItem> cartItemList = new ArrayList<>();//购物车中已经选择的商品

        Set<GoodsStandarPair> goodsStandarPairSet = new HashSet<>();
        Set<GoodsOptionPair> goodsOptionPairSet = new HashSet<>();


        for (CartItem cartItem : cart) {

            if (check && cartItem.getChecked() != true) continue;//购物车中未选择的商品直接跳过
            cartItemList.add(cartItem);
            Integer num = cartItem.getNum();
            if (num == null || num < 1) throw new BaseException(ResultCode.FAIL, "数量必须大于0");

            CartItemKey key = cartItem.getKey();
            Integer goodsId = key.getGoodsId();
            if (goodsId == null) throw new BaseException(ResultCode.FAIL, "商品id不能为null");
            Integer standarId = key.getStandarId();
            if (standarId == null) throw new BaseException(ResultCode.FAIL, "规格id不能为null");

            List<OptionIdPair> optionIdPairListForCheck = key.getOptionIdPairList();


            if (optionIdPairListForCheck != null && !optionIdPairListForCheck.isEmpty()) {


                for (OptionIdPair pair : optionIdPairListForCheck) {
                    if (pair.getOptionId() == null) {
                        throw new BaseException(ResultCode.FAIL, "属性不能为null");
                    }
                    if (pair.getSubOptionId() == null) {
                        throw new BaseException(ResultCode.FAIL, "子选项不能为null");
                    }

                    GoodsOptionPair goodsOptionPair = new GoodsOptionPair(goodsId, pair);
                    goodsOptionPairSet.add(goodsOptionPair);
                }


            } else {//传过来的参数为null或者size=0
                key.setOptionIdPairList(null);
                List<RunfastGoodsSellOption> optionWithSub = optionService.findOptionWithSub(goodsId);
                if (!optionWithSub.isEmpty()) {//商品有属性及其子选项

                    throw new BaseException(ResultCode.FAIL, "该商品设置了属性，请选择属性及其子选项");
                }

                GoodsOptionPair goodsOptionPair = new GoodsOptionPair(-1, null);
                goodsOptionPairSet.add(goodsOptionPair);
            }

            GoodsStandarPair goodsStandarPair = new GoodsStandarPair(goodsId, standarId);
            goodsStandarPairSet.add(goodsStandarPair);


        }

        /**
         * 校验规格
         */
        List<Map<String, Object>> goodsStandarList = goodsSellService.checkGoodsWithStandar(businessId, goodsStandarPairSet);
        if (goodsStandarList.size() != goodsStandarPairSet.size()) {//数据库规格记录和规格参数不匹配
            throw new BaseException(ResultCode.STANDARD_NOT_EXIST, "商品规格不存在");
        }

        /**
         * 校验属性
         */

        List<Map<String, Object>> goodsOptionList = goodsSellService.checkGoodsWithOption(businessId, goodsOptionPairSet);
        int count = 0;
        for (GoodsOptionPair goodsOptionPair : goodsOptionPairSet) {
            if (goodsOptionPair.getGoodsId() != -1) count++;
        }
        if (goodsOptionList.size() != count) {
            throw new BaseException(ResultCode.SUB_OPTION_NOT_EXIST, "商品属性不存在");
        }

        Map<String, List<Map<String, Object>>> map = new HashMap<>();
        map.put("goodsStandarList", goodsStandarList);
        map.put("goodsOptionList", goodsOptionList);

        return map;
    }


    @Override
    public Result add(Integer businessId, List<CartItem> cartItems, Integer userId, String deviceId) {

        /**
         * 计算是否该增长num还是添加新cart item
         */

        HashOperations hashOperations = redisTemplate.opsForHash();
        String key = null;
        if(userId!=null) key = Constants.REDIS_NAMESPACE_CART + userId;
        else key = Constants.REDIS_NAMESPACE_CART + deviceId;
        Cart redisCart = (Cart) hashOperations.get(key, businessId);

        if (redisCart == null) {
            redisCart = new Cart();
            ArrayList<CartItem> cartItemList = new ArrayList<>();
            redisCart.setCartItems(cartItemList);
        }

        List<CartItem> cartItemList = redisCart.getCartItems();
        for (CartItem cartItem : cartItems) {
            cartItem.setCreateTime(new Date());
            Integer num = cartItem.getNum();

            CartItemKey cartItemKey = cartItem.getKey();
            List<OptionIdPair> optionIdPairList = cartItemKey.getOptionIdPairList();
            if (optionIdPairList != null && optionIdPairList.isEmpty()) cartItemKey.setOptionIdPairList(null);


            CartItem redisCartItem = null;
            for (CartItem item : cartItemList) {
                if (cartItemKey != null && cartItemKey.equals(item.getKey())) {
                    redisCartItem = item;
                    break;
                }

            }
            if (redisCartItem == null) {//redis购物车不存在该条目

                redisCartItem = new CartItem();
                redisCartItem.setKey(cartItemKey);
                redisCartItem.setNum(1);
                redisCartItem.setChecked(true);
                redisCartItem.setCreateTime(new Date());
                cartItemList.add(redisCartItem);
            } else {
                Integer redisNum = redisCartItem.getNum();
                redisNum++;
                redisCartItem.setNum(redisNum);
                redisCartItem.setChecked(true);
            }


        }


        cartDetail(businessId, redisCart, userId, deviceId);


        //更新至redis
        hashOperations.put(key, businessId, redisCart);

        //返回当前购物车
        return Result.ok("", redisCart);
    }


    public RunfastOrderActivity getActivity(List<RunfastOrderActivity> validActivityList, Integer activityId) {
        for (RunfastOrderActivity activity : validActivityList) {
            Integer id = activity.getActivityId();
            if (id == activityId.intValue()) return activity;
        }

        return null;
    }

    private Cart cartDetail(Integer businessId, Cart redisCart, Integer userId, String deviceId) {
        RunfastBusiness business = businessService.selectByPrimaryKey(businessId);
        if (business == null) throw new BaseException(ResultCode.BUSINESS_NOT_EXIST);
        Integer agentId = business.getAgentId();


        List<CartItem> redisCartItems = redisCart.getCartItems();

        Map<String, List<Map<String, Object>>> map = this.checkCart(businessId, redisCart.getCartItems(), true);

        List<Map<String, Object>> goodsStandarList = map.get("goodsStandarList");
        List<Map<String, Object>> goodsOptionList = map.get("goodsOptionList");


        /**
         * 计算商家配送费和配送时间
         */

        BigDecimal busshowps = business.getBusshowps();
        busshowps = busshowps == null ? BigDecimal.valueOf(0) : busshowps;
        BigDecimal totalPackageFee = BigDecimal.valueOf(0d);//总的盒费

        BigDecimal cartPrice = BigDecimal.valueOf(0);//购物车条目原总价
        Integer totalNum = 0;//购物车购买数量


        Map<Integer, Map<String, Object>> sharedOffActivityMap = new HashMap<>();//同享打折特价活动购物车优惠力度map
        Map<Integer, Map<String, Object>> notSharedOffActivityMap = new HashMap<>();//不同享打折特价活动购物车优惠力度map

        Map<Integer, Integer> preCartItemStandarNumMap = new HashMap<>();//过滤相同规格，不同属性的cartItem,计算打折特价限购的时候需要


        Boolean offExist = false;//打折特价活动是否存在
        Boolean offShared = false;//打折特价活动是否同享

        for (CartItem cartItem : redisCartItems) {
            if (cartItem.getChecked() != true) continue;//购物车中未选择的商品直接跳过
            Integer num = cartItem.getNum();

            CartItemKey cartItemKey = cartItem.getKey();
            Integer goodsId = cartItemKey.getGoodsId();
            Integer standarId = cartItemKey.getStandarId();


            Map<String, Object> goodsStandar = getStandar(goodsStandarList, standarId);


            String gsName = (String) goodsStandar.get("gs_name");

            String gsImgPath = (String) goodsStandar.get("gs_imgPath");
            String gsMiniImgPath = (String) goodsStandar.get("gs_mini_imgPath");

            String gssName = (String) goodsStandar.get("gss_name");
            BigDecimal gssPrice = BigDecimal.valueOf((Double) goodsStandar.get("gss_price"));
            BigDecimal gssPackageFee = BigDecimal.valueOf(goodsStandar.get("gss_package_fee") == null ? 0 : (Double) goodsStandar.get("gss_package_fee"));

            totalPackageFee = totalPackageFee.add(gssPackageFee.multiply(BigDecimal.valueOf(num)));

            Integer aId = (Integer) goodsStandar.get("a_id");
            Integer aPtype = (Integer) goodsStandar.get("a_ptype");
            Boolean aShared = (Boolean) goodsStandar.get("a_shared");

            Boolean aIsLimited = (Boolean) goodsStandar.get("a_is_limited");
            Integer aLimitNum = (Integer) goodsStandar.get("a_limit_num");

            Double aDiscount = (Double) goodsStandar.get("a_discount");
            BigDecimal aDisprice = (Double) goodsStandar.get("a_disprice") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_disprice"));


            cartPrice = cartPrice.add(gssPrice.multiply(BigDecimal.valueOf(num)));
            totalNum += num;

            /**
             * 为打折特价活动参与最大优惠力度算法作准备
             */
            if (aId != null && aPtype != null && (aPtype == 2 || aPtype == 4)) {//打折或者特价
                offExist=true;
                offShared = aShared==null?false:aShared;

                if(userId!=null){
                    RunfastGoodsSellChildrenExample orderItemExample = new RunfastGoodsSellChildrenExample();
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(Calendar.HOUR_OF_DAY, 0);
                    calendar.set(Calendar.MINUTE, 0);
                    calendar.set(Calendar.SECOND, 0);
                    Date start = calendar.getTime();
                    calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
                    Date end = calendar.getTime();
                    orderItemExample.or().andUserIdEqualTo(userId).andGoodsSellIdEqualTo(goodsId).andGoodsSellStandardIdEqualTo(standarId)
                            .andActivityIdEqualTo(aId).andCreateTimeBetween(start, end);

                    List<RunfastGoodsSellChildren> orderItemList = orderItemService.selectByExample(orderItemExample);

                    if (orderItemList.size() > 2) {//按原价

                        goodsStandar.put("a_id", null);
                        goodsStandar.put("a_ptype", null);
                        goodsStandar.put("a_shared", null);
                        goodsStandar.put("a_is_limited", null);
                        goodsStandar.put("a_limit_num", null);
                        goodsStandar.put("a_discount", null);
                        goodsStandar.put("a_disprice", null);

                    } else {//当天享受打折特价的订单数不超过2


                        Integer preNum = preCartItemStandarNumMap.get(standarId);//当前购物车内上一个有打折特价活动的规格相同的条目的购买总数量（规格相同，属性不同的条目数量总和）

                        if (preNum == null) preNum = 0;

                        Map<String, Object> offActivity = sharedOffActivityMap.get(aId);
                        if (offActivity == null) {
                            offActivity = new HashMap<>();
                            offActivity.put("activityType", aPtype);
                            offActivity.put("shared", aShared);
                            offActivity.put("offAmount", BigDecimal.valueOf(0d));
                        }
                        BigDecimal offAmount = (BigDecimal) offActivity.get("offAmount");

                        aDisprice = aDisprice.compareTo(gssPrice) == 1 ? gssPrice : aDisprice;
                        if (aIsLimited != null && aIsLimited) {//该活动限购

                            aLimitNum = aLimitNum == null || aLimitNum < 1 ? 1 : aLimitNum;
                            if (preNum != null && preNum >= aLimitNum) {//之前条目购买数量超过限购数量，原价购买
                                goodsStandar.put("a_id", null);
                                goodsStandar.put("a_ptype", null);
                                goodsStandar.put("a_shared", null);
                                goodsStandar.put("a_is_limited", null);
                                goodsStandar.put("a_limit_num", null);
                                goodsStandar.put("a_discount", null);
                                goodsStandar.put("a_disprice", null);
                            } else {
                                int i = aLimitNum - preNum;//之前条目购买数量距离限购数量的差值
                                if (num > i) {//当前条目购买数量超出限购差值，则为未超出数量享受活动，超出数量原价购买
                                    offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(i)));
                                } else {//未超出限购数量
                                    offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(num)));
                                }
                            }


                        } else {
                            offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(num)));
                        }

                        offActivity.put("offAmount", offAmount);
                        if (aShared != null && aShared) {
                            sharedOffActivityMap.put(aId, offActivity);
                        } else {
                            notSharedOffActivityMap.put(aId, offActivity);
                        }

                        preCartItemStandarNumMap.put(standarId, preNum + num);//更新有打折特价规格的总数量


                    }
                }else{
                    Integer preNum = preCartItemStandarNumMap.get(standarId);//当前购物车内上一个有打折特价活动的规格相同的条目的购买总数量（规格相同，属性不同的条目数量总和）

                    if (preNum == null) preNum = 0;

                    Map<String, Object> offActivity = sharedOffActivityMap.get(aId);
                    if (offActivity == null) {
                        offActivity = new HashMap<>();
                        offActivity.put("activityType", aPtype);
                        offActivity.put("shared", aShared);
                        offActivity.put("offAmount", BigDecimal.valueOf(0d));
                    }
                    BigDecimal offAmount = (BigDecimal) offActivity.get("offAmount");

                    aDisprice = aDisprice.compareTo(gssPrice) == 1 ? gssPrice : aDisprice;
                    if (aIsLimited != null && aIsLimited) {//该活动限购

                        aLimitNum = aLimitNum == null || aLimitNum < 1 ? 1 : aLimitNum;
                        if (preNum != null && preNum >= aLimitNum) {//之前条目购买数量超过限购数量，原价购买
                            goodsStandar.put("a_id", null);
                            goodsStandar.put("a_ptype", null);
                            goodsStandar.put("a_shared", null);
                            goodsStandar.put("a_is_limited", null);
                            goodsStandar.put("a_limit_num", null);
                            goodsStandar.put("a_discount", null);
                            goodsStandar.put("a_disprice", null);
                        } else {
                            int i = aLimitNum - preNum;//之前条目购买数量距离限购数量的差值
                            if (num > i) {//当前条目购买数量超出限购差值，则为未超出数量享受活动，超出数量原价购买
                                offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(i)));
                            } else {//未超出限购数量
                                offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(num)));
                            }
                        }


                    } else {
                        offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(num)));
                    }

                    offActivity.put("offAmount", offAmount);
                    if (aShared != null && aShared) {
                        sharedOffActivityMap.put(aId, offActivity);
                    } else {
                        notSharedOffActivityMap.put(aId, offActivity);
                    }

                    preCartItemStandarNumMap.put(standarId, preNum + num);//更新有打折特价规格的总数量

                }



            }


        }


        BigDecimal offAmount = BigDecimal.valueOf(0d);
        List<RunfastOrderActivity> validActivityList = new ArrayList<>();
        /**
         * 根据最大优惠力度算法计算订单优惠总金额和优惠活动
         */
        BigDecimal fullPrice = cartPrice.add(totalPackageFee);
        Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, busshowps, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, null, null, false, null);

        offAmount = (BigDecimal) preferMap.get("offAmount");
        validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");


        /**
         * 根据订单满足的活动重新计算购物车条目的打折和特价
         */

        String limitTips = null;

        preCartItemStandarNumMap = new HashMap<>();//重置，过滤相同规格，不同属性的cartItem,计算打折特价限购的时候需要
        for (CartItem cartItem : redisCartItems) {
            CartItemKey cartItemKey = cartItem.getKey();
            Integer num = cartItem.getNum();
            if (cartItem.getChecked() != true) {
                standardService.updateStock(cartItemKey.getGoodsId(), cartItemKey.getStandarId(), num); //更新商品库存
                continue;//购物车中未选择的商品直接跳过
            }else{
                standardService.updateStock(cartItemKey.getGoodsId(), cartItemKey.getStandarId(), -num);
            }

            Integer goodsId = cartItemKey.getGoodsId();
            Integer standarId = cartItemKey.getStandarId();
            List<OptionIdPair> optionIdPairList = cartItemKey.getOptionIdPairList();


            Map<String, Object> goodsStandar = getStandar(goodsStandarList, standarId);


            String gsName = (String) goodsStandar.get("gs_name");
            String gsImgPath = (String) goodsStandar.get("gs_imgPath");
            String gsMiniImgPath = (String) goodsStandar.get("gs_mini_imgPath");

            String gssName = (String) goodsStandar.get("gss_name");
            BigDecimal gssPrice = BigDecimal.valueOf((Double) goodsStandar.get("gss_price"));


            Integer aId = (Integer) goodsStandar.get("a_id");
            String aName = (String) goodsStandar.get("a_name");
            Integer aPtype = (Integer) goodsStandar.get("a_ptype");
            Boolean aShared = (Boolean) goodsStandar.get("a_shared");

            Boolean aIsLimited = (Boolean) goodsStandar.get("a_is_limited");
            Integer aLimitNum = (Integer) goodsStandar.get("a_limit_num");

            BigDecimal aDiscount = (Double) goodsStandar.get("a_discount") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_discount"));
            BigDecimal aDisprice = (Double) goodsStandar.get("a_disprice") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_disprice"));


            StringBuilder goodsItemBuilder = new StringBuilder();
            goodsItemBuilder.append(gssName);

            if (optionIdPairList != null) {
                for (OptionIdPair optionIdPair : optionIdPairList) {
                    Integer subOptionId = optionIdPair.getSubOptionId();
                    Map<String, Object> goodsOption = getOption(goodsOptionList, subOptionId);

                    String sName = (String) goodsOption.get("s_name");//子选项名称
                    goodsItemBuilder.append("+" + sName);
                }
            }


            cartItem.setStandarOptionName(goodsItemBuilder.toString());


            cartItem.setGoodsName(gsName);
            cartItem.setGoodsImg(gsImgPath);
            cartItem.setStandarName(gssName);
            cartItem.setPrice(gssPrice);
            cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));

            if (aId != null) {
                if (!validActivityList.isEmpty()) {
                    RunfastOrderActivity activity = getActivity(validActivityList, aId);
                    if (activity != null) { //该规格的特价或者打折活动，经过最大优惠力度计算是可以享受的
                        Integer preNum = preCartItemStandarNumMap.get(standarId);
                        if (preNum == null) preNum = 0;


                        if (aIsLimited != null && aIsLimited) {//该活动限购
                            aDisprice = aDisprice.compareTo(gssPrice) == 1 ? gssPrice : aDisprice;
                            aLimitNum = aLimitNum == null || aLimitNum < 1 ? 1 : aLimitNum;

                            int i = aLimitNum - preNum;//之前条目购买数量距离限购数量的差值
                            if (num > i) {//当前条目购买数量超出限购差值，则为未超出数量享受活动，超出数量原价购买
                                //修改未超出条目
                                cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));

                                cartItem.setNum(num);
                                cartItem.setActivityId(aId);
                                cartItem.setActivityType(aPtype);
                                cartItem.setDisprice(aDisprice);
                                cartItem.setTotalDisprice(aDisprice.multiply(BigDecimal.valueOf(i)).add(gssPrice.multiply(BigDecimal.valueOf(num - i))));//购物车不拆分
                                limitTips = "超出限购按原价购买";
                            } else {//未超出限购数量
                                cartItem.setDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                                cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));
                                cartItem.setActivityId(aId);
                                cartItem.setActivityType(aPtype);
                                cartItem.setDisprice(aDisprice);
                                cartItem.setTotalDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                            }

                        } else {
                            cartItem.setDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                            cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));
                            cartItem.setActivityId(aId);
                            cartItem.setActivityName(aName);
                            cartItem.setActivityType(aPtype);
                            cartItem.setDisprice(aDisprice);
                            cartItem.setTotalDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                        }

                        preCartItemStandarNumMap.put(standarId, preNum + num);//更新有打折特价规格的总数量
                    }else{
                        cartItem.setNum(num);
                        cartItem.setActivityId(null);
                        cartItem.setActivityName(null);
                        cartItem.setActivityType(null);
                        cartItem.setDisprice(null);
                        cartItem.setTotalDisprice(null);
                    }
                }else{
                    cartItem.setNum(num);
                    cartItem.setActivityId(null);
                    cartItem.setActivityName(null);
                    cartItem.setActivityType(null);
                    cartItem.setDisprice(null);
                    cartItem.setTotalDisprice(null);
                }

            }else{
                cartItem.setNum(num);
                cartItem.setActivityId(null);
                cartItem.setActivityName(null);
                cartItem.setActivityType(null);
                cartItem.setDisprice(null);
                cartItem.setTotalDisprice(null);
            }
        }


        redisCart.setBusinessId(businessId);

        redisCart.setBusinessImg(business.getImgPath());
        redisCart.setBusinessName(business.getName());
        redisCart.setIsDeliver(business.getIsDeliver());

        redisCart.setBusinessName(business.getName());
        redisCart.setBusinessId(businessId);
        redisCart.setBusinessAddr(business.getAddress());
        redisCart.setBusinessAddressLng(business.getLongitude());
        redisCart.setBusinessAddressLat(business.getLatitude());
        redisCart.setBusinessMobile(business.getMobile());
        redisCart.setUserId(userId);
        redisCart.setSuportSelf(business.getSuportSelf());


        redisCart.setDeliveryFee(busshowps);

        redisCart.setTotalPackageFee(totalPackageFee);
        redisCart.setCartPrice(cartPrice);
        redisCart.setOffAmount(offAmount);


        redisCart.setTotalNum(totalNum);


        redisCart.setValidActivityList(validActivityList);


        BigDecimal cartDisprice = null;//购物车优惠后的金额,考虑打折特价活动，其他活动不考虑
        for (CartItem redisCartItem : redisCartItems) {
            BigDecimal totalDisprice = redisCartItem.getTotalDisprice();
            if (totalDisprice != null) {
                cartDisprice = cartDisprice == null ? BigDecimal.valueOf(0) : cartDisprice;
                cartDisprice = cartDisprice.add(totalDisprice);
            }

        }
        redisCart.setCartDisprice(cartDisprice);



        RunfastOrderActivity fullActivity = null;
        RunfastOrderActivity offActivity = null;

        BigDecimal finalDeliveryFee = busshowps;
        for (RunfastOrderActivity activity : validActivityList) {
            Integer activityType = activity.getActivityType();
            Boolean shared = activity.getShared();


            if (activityType == 2 || activityType == 4) {
                offActivity = activity;
            }

            if (activityType == 5 || activityType == 7) {
                BigDecimal less = BigDecimal.valueOf(activity.getLess());
                if (less.compareTo(finalDeliveryFee) == -1) {
                    finalDeliveryFee = finalDeliveryFee.subtract(less);
                } else {
                    finalDeliveryFee = BigDecimal.valueOf(0);
                }
            }

            if (activityType == 1) {
                fullActivity = activity;
            }

        }

        String shareTips = null;//活动冲突提示
        String cartTips = null;//满减提示

        //商家满减活动
        List<Integer> activityTypeList = new ArrayList<>();
        activityTypeList.add(1);


        List<TargetWithOneActivityDto> fullLessActivityList = activityService.findBusinessActivity(businessId, activityTypeList);
        Boolean fullLessExist = !fullLessActivityList.isEmpty();//满减活动是否存在
        if (fullLessExist) {
            TargetWithOneActivityDto activityDto = fullLessActivityList.get(0);

            RunfastActivity activity = activityDto.getActivity();
            Boolean fullLessShared = activity.getShared();
            fullLessShared = fullLessShared == null ? false : true;

            if (offExist && !fullLessShared&&!offShared) {
                shareTips = "满减优惠和折扣商品不能同享";
            }


        }


        redisCart.setFinalDeliveryFee(finalDeliveryFee);//最终的配送费


        BigDecimal totalPay = cartPrice.add(totalPackageFee).subtract(offAmount);
        int compareTo = totalPay.compareTo(BigDecimal.valueOf(0));
        redisCart.setTotalPay(compareTo == 1 ? totalPay : BigDecimal.valueOf(0.01));


        if (fullActivity != null ) {


            RunfastFullLessExample fullLessExample = new RunfastFullLessExample();
            fullLessExample.or().andActivity_idEqualTo(fullActivity.getActivityId());
            fullLessExample.setOrderByClause("full desc"); //按照full降序

            List<RunfastFullLess> fullLessList = fullLessService.selectByExampleWithPageable(fullLessExample, PageRequest.of(0, 5));//只取5个
//            BigDecimal price = cartDisprice == null ? cartPrice : cartDisprice;

            BigDecimal price = redisCart.getCartPrice().add(totalPackageFee);
            BigDecimal preFull = BigDecimal.valueOf(0d);
            BigDecimal preLess = BigDecimal.valueOf(0d);
            int size = fullLessList.size();
            for (int i = 0; i < size; i++) {
                RunfastFullLess fullLess = fullLessList.get(i);

                BigDecimal full = fullLess.getFull() == null ? BigDecimal.valueOf(0d) : BigDecimal.valueOf(fullLess.getFull());
                BigDecimal less = fullLess.getLess() == null ? BigDecimal.valueOf(0d) : BigDecimal.valueOf(fullLess.getLess());

                if (price.compareTo(full) == 1 || price.compareTo(full) == 0) {

                    if (i == 0) cartTips = "已满" + full + "元可减" + less + "元";
                    else cartTips = "下单减" + less + "元,再买" + (preFull.subtract(price)) + "元可减" + preLess + "元";

                    break;
                } else {
                    cartTips = "再买" + full.subtract(price) + "元可减" + less + "元";

                }
                preFull = full;
                preLess = less;

            }


        }
//        if(compareTo!=1) cartTips = "优惠额度超过商品价格，添加更多商品才能下单";

        redisCart.setCartTips(cartTips);
        redisCart.setLimitTips(limitTips);
        redisCart.setShareTips(shareTips);


        return redisCart;
    }

    private Map<String, Object> getOption(List<Map<String, Object>> goodsOptionList, int subOptionId) {
        for (Map<String, Object> goodsOption : goodsOptionList) {

            Integer sId = (Integer) goodsOption.get("s_id");
            if (sId == subOptionId) {


                return goodsOption;
            }


        }
        return null;
    }

    private Map<String, Object> getStandar(List<Map<String, Object>> goodsStandarList, int standarId) {
        for (Map<String, Object> goodsStandar : goodsStandarList) {

            Integer gsId = (Integer) goodsStandar.get("gs_id");
            Integer gssId = (Integer) goodsStandar.get("gss_id");

            if (standarId == gssId.intValue()) {
                return goodsStandar;


            }

        }
        return null;
    }


    @Override
    public Result delete(Integer businessId, List<CartItem> cartItems, Integer userId, String deviceId) {


        /**
         * 计算是否该减num还是删除cart item
         */

        if (cartItems == null || cartItems.isEmpty()) return Result.fail(ResultCode.PARAMETER_ERROR);

        HashOperations hashOperations = redisTemplate.opsForHash();

        String key = null;
        if(userId!=null) key = Constants.REDIS_NAMESPACE_CART + userId;
        else key = Constants.REDIS_NAMESPACE_CART + deviceId;

        Cart redisCart = (Cart) hashOperations.get(key, businessId);
        if (redisCart != null) {
            List<CartItem> cartItemList = redisCart.getCartItems();
            for (CartItem cartItem : cartItems) {
                CartItemKey cartItemKey = cartItem.getKey();
                List<OptionIdPair> optionIdPairList = cartItemKey.getOptionIdPairList();
                cartItemKey.setOptionIdPairList(optionIdPairList != null && optionIdPairList.isEmpty() ? null : optionIdPairList); //统一null参数

                CartItem redisCartItem = null;
                for (CartItem item : cartItemList) {
                    if (cartItemKey != null && cartItemKey.equals(item.getKey())) {
                        redisCartItem = item;
                        break;
                    }

                }
                if (redisCartItem == null) {
                    return Result.fail(ResultCode.FAIL, "购物车中不存在该购物信息");
                } else {
                    Integer num = cartItem.getNum();


                    Integer redisNum = redisCartItem.getNum();
                    if (num == null) num = redisNum;
                    if (num != null && (num > redisNum && num < 0)) num = redisNum;


                    if (redisNum == num.intValue()) {
                        cartItemList.remove(redisCartItem);
                    } else if (redisNum > num) {

                        redisNum = redisNum - num;
                        redisCartItem.setNum(redisNum);
                    }

                }
            }

        } else {
            return Result.fail(ResultCode.FAIL, "购物车中不存在该购物信息");

        }

        if (redisCart.getCartItems().isEmpty()) {
            hashOperations.delete(Constants.REDIS_NAMESPACE_CART + userId, businessId);

            return Result.ok("购物车已没有商品");
        }

        cartDetail(businessId, redisCart, userId, deviceId);
        //购物车数据同步至redis
        hashOperations.put(Constants.REDIS_NAMESPACE_CART + userId, businessId, redisCart);

        //返回当前购物车
        return Result.ok("", redisCart);
    }

    @Override
    public Result fillInDiy(double userLng, double userLat, Integer businessId, Cart redisCart, Integer toAddressId, Date selfTime, String selfMobile, Boolean eatInBusiness, Integer userRedId, Integer userCouponId, Date bookTime, Integer userId) {

        RunfastBusiness business = businessService.selectByPrimaryKey(businessId);
        if (business == null) return Result.fail(ResultCode.BUSINESS_NOT_EXIST);
        Integer agentId = business.getAgentId();

        RunfastDeliverCost defaultDeliveryTemplate = deliverCostService.getDefaultDeliveryTemplate(agentId);
        Date deliveryStart1 = defaultDeliveryTemplate.getStartTimeDay1();
        Date deliveryEnd1 = defaultDeliveryTemplate.getEndTimeDay1();
        Date deliveryStart2 = defaultDeliveryTemplate.getStartTimeNight2();
        Date deliveryEnd2 = defaultDeliveryTemplate.getEndTimeNight2();

        BusinessDto businessDto = null;
        Boolean suportSelf = null;
        if(toAddressId!=null) {
            suportSelf = false;

            RunfastCuseraddress cuseraddress = cuseraddressService.selectByPrimaryKey(toAddressId);
            Double toLng = Double.valueOf(cuseraddress.getLongitude());
            Double toLat = Double.valueOf(cuseraddress.getLatitude());


            businessDto = businessService.detailWithIsOpen(businessId, toLng, toLat,deliveryStart1,deliveryEnd1,deliveryStart2,deliveryEnd2);


            /**
             * 是否超出配送距离
             */


            Double longitude = Double.valueOf(cuseraddress.getLongitude());
            Double latitude = Double.valueOf(cuseraddress.getLatitude());

            Double distance = businessDto.getDistance();//以米为单位

            Double maxDistance = defaultDeliveryTemplate.getMaxDistance();//以公里为单位
            String distRange = defaultDeliveryTemplate.getDistRange();

            if (maxDistance != null) {
                if (distance > maxDistance * 1000) {

                    return Result.fail(ResultCode.FAIL, "超出配送距离");
                }

            } else if (StringUtils.isNotBlank(distRange)) {

                Point2D.Double piont = new Point2D.Double(latitude, longitude);

                List<Point2D.Double> psList = new ArrayList<Point2D.Double>();
                String ps[] = distRange.split("\\|");

                for (String p : ps) {
                    if (StringUtils.isNotBlank(p)) {
                        String xs[] = p.split(",");
                        if (xs.length > 1) {
                            Point2D.Double p2d = new Point2D.Double(Double.parseDouble(xs[1]), Double.parseDouble(xs[0]));
                            psList.add(p2d);
                        }
                    }

                }

                if (!GeoUtil.IsPtInPoly(piont, psList)) return Result.fail(ResultCode.FAIL, "超出配送范围");
            }


            redisCart.setUserName(cuseraddress.getName());
            redisCart.setUserMobile(cuseraddress.getMobile());
            redisCart.setUserPhone(cuseraddress.getPhone());
            redisCart.setUserAddress(cuseraddress.getUserAddress());
            redisCart.setAddress(cuseraddress.getAddress());
            redisCart.setUserAddressLng(cuseraddress.getLongitude());
            redisCart.setUserAddressLat(cuseraddress.getLatitude());
            redisCart.setUserAddressId(toAddressId);
            redisCart.setUserAddressTag(cuseraddress.getTag());
            redisCart.setUserAddressGender(cuseraddress.getGender());
        }
        else if(selfMobile!=null&&selfTime!=null) {
            suportSelf = true;

            Validate.notNull(selfTime, "自取时间不能为空");
            Validate.notNull(selfTime, "自取手机号不能为空");
            redisCart.setSelfTime(selfTime);
            redisCart.setSelfMobile(selfMobile);

            businessDto = businessService.detailWithIsOpen(businessId, userLng, userLat,deliveryStart1,deliveryEnd1,deliveryStart2,deliveryEnd2);
            businessDto.setDistance(null);
        }
        else {
            businessDto = businessService.detailWithIsOpen(businessId, userLng, userLat,deliveryStart1,deliveryEnd1,deliveryStart2,deliveryEnd2);
            businessDto.setDistance(null);
        }

        redisCart.setUserSuportSelf(suportSelf);

        Integer isopen = businessDto.getIsopen();
        if(isopen!=null&&isopen!=1) return Result.fail(ResultCode.FAIL, "商家已休息");

        List<CartItem> redisCartItems = redisCart.getCartItems();


        Map<String, List<Map<String, Object>>> map = this.checkCart(businessId, redisCartItems, true);
        List<Map<String, Object>> goodsStandarList = map.get("goodsStandarList");
        List<Map<String, Object>> goodsOptionList = map.get("goodsOptionList");

        /**
         * 计算商家配送费和配送时间
         */

        Map<String, Object> deliveryInfo = businessService.getDeliveryInfo(businessDto);
        BigDecimal deliveryFee = (BigDecimal) deliveryInfo.get("deliveryFee");
        if (suportSelf != null && suportSelf) deliveryFee = BigDecimal.valueOf(0);

        Integer deliveryDuration = (Integer) deliveryInfo.get("deliveryDuration");


        BigDecimal cartPrice = BigDecimal.valueOf(0d);//购物车条目原总价
        Integer totalNum = 0;//购物车购买数量

        BigDecimal totalPackageFee = BigDecimal.valueOf(0d);//总的盒费

        Map<Integer, Map<String, Object>> sharedOffActivityMap = new HashMap<>();//同享打折特价活动购物车优惠力度map
        Map<Integer, Map<String, Object>> notSharedOffActivityMap = new HashMap<>();//不同享打折特价活动购物车优惠力度map

        Map<Integer, Integer> preCartItemStandarNumMap = new HashMap<>();//过滤相同规格，不同属性的cartItem,计算打折特价限购的时候需要

        Boolean offExist = false;//打折特价活动是否存在
        Boolean offShared = false;//打折特价活动是否同享


        Boolean requiredExist = false;//必点商品是否存在
        for (CartItem cartItem : redisCartItems) {

            if (cartItem.getChecked() != true) continue;//购物车中未选择的商品直接跳过
            Integer num = cartItem.getNum();

            CartItemKey cartItemKey = cartItem.getKey();
            Integer goodsId = cartItemKey.getGoodsId();
            Integer standarId = cartItemKey.getStandarId();


            Map<String, Object> goodsStandar = getStandar(goodsStandarList, standarId);

            String gsName = (String) goodsStandar.get("gs_name");
            String gsImgPath = (String) goodsStandar.get("gs_imgPath");
            String gsMiniImgPath = (String) goodsStandar.get("gs_mini_imgPath");
            Boolean gsRequired = (Boolean) goodsStandar.get("gs_required");

            if(gsRequired!=null&&gsRequired) requiredExist = true;

            String gssName = (String) goodsStandar.get("gss_name");
            BigDecimal gssPrice = BigDecimal.valueOf((Double) goodsStandar.get("gss_price"));
            BigDecimal gssPackageFee = (Double) goodsStandar.get("gss_package_fee") == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf((Double) goodsStandar.get("gss_package_fee"));

            totalPackageFee = totalPackageFee.add(gssPackageFee.multiply(BigDecimal.valueOf(num)));


            Integer aId = (Integer) goodsStandar.get("a_id");
            String aName = (String) goodsStandar.get("a_name");
            Integer aPtype = (Integer) goodsStandar.get("a_ptype");
            Boolean aShared = (Boolean) goodsStandar.get("a_shared");

            Boolean aIsLimited = (Boolean) goodsStandar.get("a_is_limited");
            Integer aLimitNum = (Integer) goodsStandar.get("a_limit_num");

            BigDecimal aDiscount = (Double) goodsStandar.get("a_discount") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_discount"));
            BigDecimal aDisprice = (Double) goodsStandar.get("a_disprice") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_disprice"));


            cartPrice = cartPrice.add(gssPrice.multiply(BigDecimal.valueOf(num)));
            totalNum += num;

            /**
             * 为打折特价活动参与最大优惠力度算法作准备
             */
            if (aId != null && aPtype != null && (aPtype == 2 || aPtype == 4)) {//打折或者特价

                offExist=true;
                offShared = aShared==null?false:aShared;

                RunfastGoodsSellChildrenExample orderItemExample = new RunfastGoodsSellChildrenExample();
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                Date start = calendar.getTime();
                calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
                Date end = calendar.getTime();
                orderItemExample.or().andUserIdEqualTo(userId).andGoodsSellIdEqualTo(goodsId).andGoodsSellStandardIdEqualTo(standarId)
                        .andActivityIdEqualTo(aId).andCreateTimeBetween(start, end);

                List<RunfastGoodsSellChildren> orderItemList = orderItemService.findGroupByOrderId(orderItemExample);

                if (orderItemList.size() > 2) {//按原价

                    goodsStandar.put("a_id", null);
                    goodsStandar.put("a_ptype", null);
                    goodsStandar.put("a_shared", null);
                    goodsStandar.put("a_is_limited", null);
                    goodsStandar.put("a_limit_num", null);
                    goodsStandar.put("a_discount", null);
                    goodsStandar.put("a_disprice", null);

                } else {//当天享受打折特价的订单数不超过2


                    Integer preNum = preCartItemStandarNumMap.get(standarId);//当前购物车内上一个有打折特价活动的规格相同的条目的购买总数量（规格相同，属性不同的条目数量总和）

                    if (preNum == null) preNum = 0;

                    Map<String, Object> offActivity = sharedOffActivityMap.get(aId);
                    if (offActivity == null) {
                        offActivity = new HashMap<>();
                        offActivity.put("activityType", aPtype);
                        offActivity.put("shared", aShared);
                        offActivity.put("offAmount", BigDecimal.valueOf(0d));
                    }
                    BigDecimal offAmount = (BigDecimal) offActivity.get("offAmount");
                    aDisprice = aDisprice == null ? BigDecimal.valueOf(0) : aDisprice;
                    aDisprice = aDisprice.compareTo(gssPrice) == 1 ? gssPrice : aDisprice;
                    if (aIsLimited == null || aIsLimited) {//该活动限购

                        aLimitNum = aLimitNum == null || aLimitNum < 1 ? 1 : aLimitNum;

                        if (preNum != null && preNum >= aLimitNum) {//之前条目购买数量超过限购数量，原价购买
                            goodsStandar.put("a_id", null);
                            goodsStandar.put("a_ptype", null);
                            goodsStandar.put("a_shared", null);
                            goodsStandar.put("a_is_limited", null);
                            goodsStandar.put("a_limit_num", null);
                            goodsStandar.put("a_discount", null);
                            goodsStandar.put("a_disprice", null);
                        } else {
                            int i = aLimitNum - preNum;//之前条目购买数量距离限购数量的差值
                            if (num > i) {//当前条目购买数量超出限购差值，则为未超出数量享受活动，超出数量原价购买
                                offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(i)));
                            } else {//未超出限购数量
                                offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(num)));
                            }
                        }


                    } else {
                        offAmount = offAmount.add((gssPrice.subtract(aDisprice)).multiply(BigDecimal.valueOf(num)));
                    }

                    offActivity.put("offAmount", offAmount);
                    if (aShared != null && aShared) {
                        sharedOffActivityMap.put(aId, offActivity);
                    } else {
                        notSharedOffActivityMap.put(aId, offActivity);
                    }

                    preCartItemStandarNumMap.put(standarId, preNum + num);//更新有打折特价规格的总数量


                }


            }


        }

        Long countOfRequired = goodsSellService.countOfRequired(businessId);
        if(countOfRequired!=null&&countOfRequired>0&&!requiredExist) return Result.fail(ResultCode.FAIL, "需要选择必点商品才可以下单");


        BigDecimal offAmount = BigDecimal.valueOf(0);
        List<RunfastOrderActivity> validActivityList = new ArrayList<>();
        /**
         * 根据最大优惠力度算法计算订单优惠总金额和优惠活动
         */

        RedPacketRecordWithOneRedActivityDto commonRedActivity = null;
        Integer commonRedActivityType = null;
        Boolean commonShared = null;
        if (userRedId != null) {//选择了通用红包,有即享受，不考虑是否同享


            commonRedActivity = redPacketRecordService.getRedPacketRecordWithOneRedActivity(userRedId);
            if (commonRedActivity == null) return Result.fail(ResultCode.FAIL, "该红包无效");
            RunfastActivity redActivity = commonRedActivity.getActivity();

            Integer activityType = redActivity.getPtype();
            if (activityType != 12) return Result.fail(ResultCode.PARAMETER_ERROR, "不是通用红包");

            commonRedActivityType = activityType;
            commonShared = redActivity.getShared();
            commonShared = commonShared == null ? false : commonShared;

        }


        if (eatInBusiness != null && eatInBusiness) { //堂食，不需要餐盒费

            totalPackageFee = BigDecimal.valueOf(0);
        }

        BigDecimal fullPrice = cartPrice.add(totalPackageFee);
        RedPacketRecordWithOneRedActivityDto couponActivity = null;
        Integer couponActivityType = null;

        Boolean couponShared = null;

        if (userCouponId != null) {


            couponActivity = redPacketRecordService.getRedPacketRecordWithOneRedActivity(userCouponId);
            if (couponActivity == null) return Result.fail(ResultCode.FAIL, "该红包无效");
            RunfastActivity redActivity = couponActivity.getActivity();
            Integer activityType = redActivity.getPtype();
            if (activityType != 10 && activityType != 11) return Result.fail(ResultCode.PARAMETER_ERROR, "不是商家优惠券");
            couponActivityType = activityType;
            couponShared = redActivity.getShared();
            couponShared = couponShared == null ? false : couponShared;

        }

        String redTips = null;
        if (commonRedActivityType != null && couponActivityType != null) { //同时选择


            Double commonLess = commonRedActivity.getLess();
            Double couponLess = couponActivity.getLess();

            if (!commonShared && !couponShared) { //都不同享
                redTips = "通用红包和商家优惠券不同享";
                if (commonLess >= couponLess) { //考虑优惠力度
                    Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, commonRedActivity, null, true, suportSelf);

                    offAmount = (BigDecimal) preferMap.get("offAmount");
                    validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");
                } else {
                    Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, null, couponActivity, true, suportSelf);

                    offAmount = (BigDecimal) preferMap.get("offAmount");
                    validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");
                }


            } else if (commonShared && couponShared) { //都同享
                Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, commonRedActivity, couponActivity, true, suportSelf);

                offAmount = (BigDecimal) preferMap.get("offAmount");
                validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");

            } else { //有一个是同享
                redTips = "通用红包和商家优惠券不同享";
                if (commonLess >= couponLess) { //考虑优惠力度
                    Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, commonRedActivity, null, true, suportSelf);

                    offAmount = (BigDecimal) preferMap.get("offAmount");
                    validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");
                } else {
                    Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, null, couponActivity, true, suportSelf);

                    offAmount = (BigDecimal) preferMap.get("offAmount");
                    validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");
                }

            }


        } else if (commonRedActivityType == null && couponActivityType == null) { //都不选

            Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, null, null, true, suportSelf);

            offAmount = (BigDecimal) preferMap.get("offAmount");
            validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");
        } else { //选择一个

            Boolean shared = null;
            RedPacketRecordWithOneRedActivityDto redActivity = null;
            if (commonRedActivityType != null) {
                shared = commonShared;
                redActivity = commonRedActivity;
            } else {
                shared = couponShared;
                redActivity = couponActivity;
            }

            if (shared) {
                Map<String, Object> preferMap = getPreferMap(businessId, userId, agentId, deliveryFee, fullPrice, sharedOffActivityMap, notSharedOffActivityMap, commonRedActivity, couponActivity, true, suportSelf);

                offAmount = (BigDecimal) preferMap.get("offAmount");
                validActivityList = (List<RunfastOrderActivity>) preferMap.get("validActivityList");
            } else { //红包与其他活动不同享，则不考虑(除了免配送费和新用户活动)其他活动

                //获取免运费,新用户活动,红包活动,有即享受，不参与最大优惠力度算法
                List<Object> alwaysSharedActivityList = getAlwaysSharedActivityList(businessId, deliveryFee, suportSelf);
                alwaysSharedActivityList.add(redActivity);

                Map<String, Object> shareMap = getSharedMap(userId, agentId, fullPrice, deliveryFee, alwaysSharedActivityList);
                offAmount = (BigDecimal) shareMap.get("sharedOffAmount");
                validActivityList = (List<RunfastOrderActivity>) shareMap.get("sharedValidActivityList");
            }


        }


        redisCart.setRedTips(redTips);
        /**
         * 根据订单满足的活动重新计算购物车条目的打折和特价
         */

        String limitTips = null;
        preCartItemStandarNumMap = new HashMap<>();//重置，过滤相同规格，不同属性的cartItem,计算打折特价限购的时候需要

        List<CartItem> frontCartItems = new ArrayList<>();
        for (CartItem cartItem : redisCartItems) {
            frontCartItems.add(cartItem);
            if (cartItem.getChecked() != true) continue;//购物车中未选择的商品直接跳过
            Integer num = cartItem.getNum();

            CartItemKey cartItemKey = cartItem.getKey();
            Integer goodsId = cartItemKey.getGoodsId();
            Integer standarId = cartItemKey.getStandarId();
            List<OptionIdPair> optionIdPairList = cartItemKey.getOptionIdPairList();


            Map<String, Object> goodsStandar = getStandar(goodsStandarList, standarId);


            String gsName = (String) goodsStandar.get("gs_name");
            String gsImgPath = (String) goodsStandar.get("gs_imgPath");
            String gsMiniImgPath = (String) goodsStandar.get("gs_mini_imgPath");

            String gssName = (String) goodsStandar.get("gss_name");
            BigDecimal gssPrice = BigDecimal.valueOf((Double) goodsStandar.get("gss_price"));
//            BigDecimal gssPackageFee = (Double) goodsStandar.get("gss_package_fee") == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf((Double) goodsStandar.get("gss_package_fee"));
//
//            totalPackageFee = totalPackageFee.add(gssPackageFee.multiply(BigDecimal.valueOf(num)));

            Integer aId = (Integer) goodsStandar.get("a_id");
            String aName = (String) goodsStandar.get("a_name");
            Integer aPtype = (Integer) goodsStandar.get("a_ptype");
            Boolean aShared = (Boolean) goodsStandar.get("a_shared");

            Boolean aIsLimited = (Boolean) goodsStandar.get("a_is_limited");
            Integer aLimitNum = (Integer) goodsStandar.get("a_limit_num");

            BigDecimal aDiscount = (Double) goodsStandar.get("a_discount") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_discount"));
            BigDecimal aDisprice = (Double) goodsStandar.get("a_disprice") == null ? null : BigDecimal.valueOf((Double) goodsStandar.get("a_disprice"));


            StringBuilder goodsItemBuilder = new StringBuilder();
            goodsItemBuilder.append(gssName);

            if (optionIdPairList != null) {
                for (OptionIdPair optionIdPair : optionIdPairList) {
                    Integer subOptionId = optionIdPair.getSubOptionId();
                    Map<String, Object> goodsOption = getOption(goodsOptionList, subOptionId);

                    String sName = (String) goodsOption.get("s_name");//子选项名称
                    goodsItemBuilder.append("+" + sName);
                }
            }

            cartItem.setStandarOptionName(goodsItemBuilder.toString());


            cartItem.setGoodsName(gsName);
            cartItem.setGoodsImg(gsImgPath);
            cartItem.setStandarName(gssName);
            cartItem.setPrice(gssPrice);
            cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));

            if (aId != null) {
                if (!validActivityList.isEmpty()) {
                    RunfastOrderActivity activity = getActivity(validActivityList, aId);
                    if (activity != null) { //该规格的特价或者打折活动，经过最大优惠力度计算是可以享受的
                        Integer preNum = preCartItemStandarNumMap.get(standarId);
                        if (preNum == null) preNum = 0;


                        if (aIsLimited == null || aIsLimited) { //该活动限购
                            aDisprice = aDisprice == null ? BigDecimal.valueOf(0) : aDisprice;
                            aDisprice = aDisprice.compareTo(gssPrice) == 1 ? gssPrice : aDisprice;
                            aLimitNum = aLimitNum == null || aLimitNum < 1 ? 1 : aLimitNum;

                            int i = aLimitNum - preNum;//之前条目购买数量距离限购数量的差值
                            if (num > i) {//当前条目购买数量超出限购差值，则为未超出数量享受活动，超出数量原价购买
                                //修改未超出条目
                                cartItem.setPrice(gssPrice);
                                cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(i)));

                                cartItem.setNum(i);
                                cartItem.setActivityId(aId);
                                cartItem.setActivityName(aName);
                                cartItem.setActivityType(aPtype);
                                cartItem.setDisprice(aDisprice);
                                cartItem.setTotalDisprice(aDisprice.multiply(BigDecimal.valueOf(i)));

                                //修改超出条目
                                int exccedNum = num - i;
                                CartItem exceedCartItem = new CartItem();
                                exceedCartItem.setStandarOptionName(goodsItemBuilder.toString());


                                exceedCartItem.setKey(cartItem.getKey());
                                exceedCartItem.setGoodsName(gsName);
                                exceedCartItem.setGoodsImg(gsImgPath);
                                exceedCartItem.setStandarName(gssName);
                                exceedCartItem.setNum(exccedNum);
                                exceedCartItem.setPrice(gssPrice);
                                exceedCartItem.setCreateTime(cartItem.getCreateTime());
                                exceedCartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(exccedNum)));
                                exceedCartItem.setChecked(true);
                                frontCartItems.add(exceedCartItem);//保存超出原价购买的条目

                                limitTips = "超出限购按原价购买";
                            } else {//未超出限购数量
                                cartItem.setDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                                cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));
                                cartItem.setActivityId(aId);
                                cartItem.setActivityName(aName);
                                cartItem.setActivityType(aPtype);
                                cartItem.setDisprice(aDisprice);
                                cartItem.setTotalDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                            }
                        } else {
                            cartItem.setDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                            cartItem.setTotalPrice(gssPrice.multiply(BigDecimal.valueOf(num)));
                            cartItem.setActivityId(aId);
                            cartItem.setActivityName(aName);
                            cartItem.setActivityType(aPtype);
                            cartItem.setDisprice(aDisprice);
                            cartItem.setTotalDisprice(aDisprice.multiply(BigDecimal.valueOf(num)));
                        }

                        preCartItemStandarNumMap.put(standarId, preNum + num);//更新有打折特价规格的总数量


                    }else{
                        cartItem.setNum(num);
                        cartItem.setActivityId(null);
                        cartItem.setActivityName(null);
                        cartItem.setActivityType(null);
                        cartItem.setDisprice(null);
                        cartItem.setTotalDisprice(null);
                    }
                }else{
                    cartItem.setNum(num);
                    cartItem.setActivityId(null);
                    cartItem.setActivityName(null);
                    cartItem.setActivityType(null);
                    cartItem.setDisprice(null);
                    cartItem.setTotalDisprice(null);
                }

            }else{
                cartItem.setNum(num);
                cartItem.setActivityId(null);
                cartItem.setActivityName(null);
                cartItem.setActivityType(null);
                cartItem.setDisprice(null);
                cartItem.setTotalDisprice(null);
            }
        }
        redisCart.setCartItems(frontCartItems);

        /**
         * 按购物车条目添加的时间降序
         */
        frontCartItems.sort(new Comparator<CartItem>() {
            @Override
            public int compare(CartItem o1, CartItem o2) {
                Date createTime1 = o1.getCreateTime();
                Date createTime2 = o2.getCreateTime();
                if (createTime1 != null && createTime2 != null) return createTime1.compareTo(createTime2);
                else return 1;
            }
        });


        redisCart.setBusinessId(businessId);

        redisCart.setBusinessImg(business.getImgPath());
        redisCart.setBusinessName(business.getName());
        redisCart.setIsDeliver(business.getIsDeliver());

        redisCart.setBusinessName(business.getName());
        redisCart.setBusinessId(businessId);
        redisCart.setBusinessAddr(business.getAddress());
        redisCart.setBusinessAddressLng(business.getLongitude());
        redisCart.setBusinessAddressLat(business.getLatitude());
        redisCart.setBusinessMobile(business.getMobile());
        redisCart.setUserId(userId);
        redisCart.setSuportSelf(business.getSuportSelf());


        redisCart.setDeliveryFee(deliveryFee);
        redisCart.setDeliveryDuration(deliveryDuration);

        Calendar now = Calendar.getInstance();
        now.add(Calendar.MINUTE, deliveryDuration);
        redisCart.setDisTime(now.getTime());

        if (bookTime == null) {
            redisCart.setBooked(false);
        } else {
            redisCart.setBooked(true);
            redisCart.setBookTime(bookTime);
        }


        redisCart.setTotalPackageFee(totalPackageFee);

        redisCart.setCartPrice(cartPrice);
        redisCart.setOffAmount(offAmount);


        redisCart.setDistance(businessDto.getDistance() == null ? null : businessDto.getDistance().intValue());
        redisCart.setTotalNum(totalNum);
        redisCart.setUserRedId(userRedId);
        redisCart.setUserCouponId(userCouponId);


        redisCart.setValidActivityList(validActivityList);


        BigDecimal cartDisprice = null;//购物车优惠后的金额,考虑打折特价活动，其他活动不考虑
        for (CartItem redisCartItem : redisCartItems) {
            BigDecimal totalDisprice = redisCartItem.getTotalDisprice();
            if (totalDisprice != null) {
                cartDisprice = cartDisprice == null ? BigDecimal.valueOf(0) : cartDisprice;
                cartDisprice = cartDisprice.add(totalDisprice);
            }

        }
        redisCart.setCartDisprice(cartDisprice);


        String cartTips = null;//活动冲突提示

        //商家满减活动
        List<Integer> activityTypeList = new ArrayList<>();
        activityTypeList.add(1);

        List<TargetWithOneActivityDto> fullLessActivityList = activityService.findBusinessActivity(businessId, activityTypeList);
        Boolean fullLessExist = !fullLessActivityList.isEmpty();//满减活动是否存在

        if (fullLessExist) {
            TargetWithOneActivityDto activityDto = fullLessActivityList.get(0);

            RunfastActivity activity = activityDto.getActivity();
            Boolean fullLessShared = activity.getShared();
            fullLessShared = fullLessShared == null ? false : true;

            if (offExist) {
                cartTips = "满减优惠和折扣商品不能同享";
            }


        }



        BigDecimal finalDeliveryFee = deliveryFee;
        for (RunfastOrderActivity activity : validActivityList) {
            Integer activityType = activity.getActivityType();
            Boolean shared = activity.getShared();

            if (activityType == 5 || activityType == 7) {
                BigDecimal less = BigDecimal.valueOf(activity.getLess());
                if (less.compareTo(finalDeliveryFee) == -1) {
                    finalDeliveryFee = finalDeliveryFee.subtract(less);
                } else {
                    finalDeliveryFee = BigDecimal.valueOf(0);
                }
            }


        }
        redisCart.setFinalDeliveryFee(finalDeliveryFee);//最终的配送费


        redisCart.setCartTips(cartTips);
        redisCart.setLimitTips(limitTips);

        BigDecimal totalPay = cartPrice.add(totalPackageFee).add(deliveryFee).subtract(offAmount);
        int compareTo = totalPay.compareTo(BigDecimal.valueOf(0));
        redisCart.setTotalPay(compareTo == 1 ? totalPay : BigDecimal.valueOf(0.01));



        HashOperations hashOperations = redisTemplate.opsForHash();

        /**
         * 更新购物车
         */
//        hashOperations.put(Constants.REDIS_NAMESPACE_CART + userId, businessId, redisCart);

        /**
         * 并更新redis预订单，准备正式下单
         */
        hashOperations.put(Constants.REDIS_NAMESPACE_PREORDER + userId, businessId, redisCart);


        return Result.ok("", redisCart);
    }


    @Override
    public Result list(int businessId, Integer userId) {
        RunfastBusiness business = businessService.selectByPrimaryKey(businessId);
        if (business == null) return Result.fail(ResultCode.BUSINESS_NOT_EXIST);

        HashOperations hashOperations = redisTemplate.opsForHash();
        Cart redisCart = (Cart) hashOperations.get(Constants.REDIS_NAMESPACE_CART + userId, businessId);
        if (redisCart == null) return Result.ok("");
        List<CartItem> cartItems = redisCart.getCartItems();
        if (cartItems == null) {
            //返回当前购物车
            return Result.ok("");
        } else {
            //返回当前购物车
            return Result.ok("", redisCart);
        }
    }

    @Override
    public List<Cart> list(Integer userId) {

        HashOperations hashOperations = redisTemplate.opsForHash();
        List<Cart> redisCartList = (List<Cart>) hashOperations.values(Constants.REDIS_NAMESPACE_CART + userId);
        return redisCartList;

    }

    /**
     * 封装最大优惠力度算法
     *
     * @param businessId
     * @param userId
     * @param agentId
     * @param deliveryFee
     * @param cartPrice
     * @param sharedOffActivityMap
     * @param notSharedOffActivityMap
     * @param commonRedActivity
     * @param couponActivity
     * @param takeAlwayShared         是否将免运费,新用户,红包活动纳入计算
     * @return
     */
    private Map<String, Object> getPreferMap(Integer businessId, Integer userId, Integer agentId, BigDecimal deliveryFee, BigDecimal cartPrice, Map<Integer, Map<String, Object>> sharedOffActivityMap, Map<Integer, Map<String, Object>> notSharedOffActivityMap, RedPacketRecordWithOneRedActivityDto commonRedActivity, RedPacketRecordWithOneRedActivityDto couponActivity, boolean takeAlwayShared, Boolean suportSelf) {
        //  活动类型：1满减  2打折3赠品4特价5满减免运费6优惠券7免部分配送费8新用户立减活动9首单立减活动10商户红包11下单返红包,(新用户立减即首单立减)
        List<Object> sharedActivityList = new ArrayList<>(); //同享的活动列表
        List<Object> notSharedActivityList = new ArrayList<>(); //不同享的活动列表

        sharedActivityList.addAll(sharedOffActivityMap.entrySet());//保存打折特价同享活动
        notSharedActivityList.addAll(notSharedOffActivityMap.entrySet());//保存打折特价不同享活动


        //保存满减活动
        List<Integer> activityTypeList = new ArrayList<>();
        activityTypeList.add(1);

        //存在多个同类型的活动
        List<TargetWithOneActivityDto> businessActivityList = activityService.findBusinessActivity(businessId, activityTypeList);


        for (TargetWithOneActivityDto activityTarget : businessActivityList) {
            RunfastActivity activity = activityTarget.getActivity();
            Boolean shared1 = activity.getShared();
            if (shared1 != null && shared1) {//同享
                sharedActivityList.add(activity);
            } else {
                notSharedActivityList.add(activity);
            }

        }

        Map<String, Object> sharedMap = getSharedMap(userId, agentId, cartPrice, deliveryFee, sharedActivityList);
        BigDecimal sharedOffAmount = (BigDecimal) sharedMap.get("sharedOffAmount");
        List<RunfastOrderActivity> sharedValidActivityList = (List<RunfastOrderActivity>) sharedMap.get("sharedValidActivityList");

        Map<String, Object> notSharedMap = getNotSharedMap(userId, agentId, cartPrice, deliveryFee, notSharedActivityList);
        BigDecimal notSharedOffAmount = (BigDecimal) notSharedMap.get("notSharedOffAmount");
        List<RunfastOrderActivity> notSharedValidActivityList = (List<RunfastOrderActivity>) notSharedMap.get("notSharedValidActivityList");


        BigDecimal offAmount = BigDecimal.valueOf(0);
        List<RunfastOrderActivity> validActivityList = new ArrayList<>();


        //对比同享活动和不同享活动的优惠力度
        /*if (sharedOffAmount.compareTo(notSharedOffAmount) == 1) {
            offAmount = offAmount.add(sharedOffAmount);
            validActivityList.addAll(sharedValidActivityList);
        } else {
            offAmount = offAmount.add(notSharedOffAmount);
            validActivityList.addAll(notSharedValidActivityList);
        }*/

        //改为所有活动同享即享受
        offAmount = offAmount.add(sharedOffAmount).add(notSharedOffAmount);
        validActivityList.addAll(sharedValidActivityList);
        validActivityList.addAll(notSharedValidActivityList);


        if (takeAlwayShared) {
            //免运费,新用户有即享受，不参与最大优惠力度算法
            List<Object> alwaysSharedActivityList = getAlwaysSharedActivityList(businessId, deliveryFee, suportSelf);

            if (commonRedActivity != null) alwaysSharedActivityList.add(commonRedActivity);
            if (couponActivity != null) alwaysSharedActivityList.add(couponActivity);
            Map<String, Object> alwaysharedMap = getSharedMap(userId, agentId, cartPrice, deliveryFee, alwaysSharedActivityList);
            BigDecimal alwaySharedOffAmount = (BigDecimal) alwaysharedMap.get("sharedOffAmount");
            List<RunfastOrderActivity> alwaySharedValidActivityList = (List<RunfastOrderActivity>) alwaysharedMap.get("sharedValidActivityList");

            offAmount = offAmount.add(alwaySharedOffAmount);
            validActivityList.addAll(alwaySharedValidActivityList);
        }


        Map<String, Object> map = new HashMap<>();
        map.put("offAmount", offAmount);
        map.put("validActivityList", validActivityList);

        return map;

    }


    /**
     * 获取免运费和新用户活动(有即享受活动)
     *
     * @param businessId
     * @param deliveryFee
     */
    private List<Object> getAlwaysSharedActivityList(Integer businessId, BigDecimal deliveryFee, Boolean suportSelf) {
        List<Object> alwaySharedActivityList = new ArrayList<>();
        List<Integer> activityTypeList = new ArrayList<>();
        if (suportSelf == null || !suportSelf) { //非自取才考虑免配送费活动
            activityTypeList.add(5);
            activityTypeList.add(7);
        }

        activityTypeList.add(8);

        List<TargetWithOneActivityDto> businessActivityList = activityService.findBusinessActivity(businessId, activityTypeList);

        /**
         * 同时存在全免运费和免部分运费，取优惠力度大的
         */
        BigDecimal deliveryOffAmount = BigDecimal.valueOf(0);//配送费优惠金额
        RunfastActivity deliveryActivity = null;//订单参与的免配送费活动
        for (TargetWithOneActivityDto activityTarget : businessActivityList) {
            RunfastActivity activity = activityTarget.getActivity();
            Integer ptype = activity.getPtype();

            switch (ptype) {
                case 5:
                    if (deliveryFee.compareTo(deliveryOffAmount) == 1) {
                        deliveryOffAmount = deliveryFee;
                        deliveryActivity = activity;
                    }
                    break;
                case 7:
                    BigDecimal less = BigDecimal.valueOf(activity.getLesss()==null?0D:activity.getLesss());
                    if (less.compareTo(deliveryOffAmount) == 1) {
                        deliveryOffAmount = less;
                        deliveryActivity = activity;
                    }
                    break;
                case 8:
                    alwaySharedActivityList.add(activity);//新用户活动
                    break;
            }

        }

        if (deliveryActivity != null) alwaySharedActivityList.add(deliveryActivity);

        return alwaySharedActivityList;
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> getSharedMap(Integer userId, Integer agentId, BigDecimal cartPrice, BigDecimal deliveryFee, List<Object> sharedActivityList) {
        BigDecimal shareOffAmount = BigDecimal.valueOf(0); //同享活动优惠总金额

        Map<String, Object> map = new HashMap<>();


        List<RunfastOrderActivity> sharedValidActivityList = new ArrayList<>();
        Boolean exceed = false;//活动优惠的总金额是否超过原价
        for (Object object : sharedActivityList) {

            int i = shareOffAmount.compareTo(cartPrice);
            if (i == 1 || i == 0) exceed = true;

            //  活动类型：1满减  2打折3赠品4特价5满减免运费6优惠券7免部分配送费8新用户立减活动9首单立减活动10商户红包11下单返红包,(新用户立减即首单立减)

            Integer activityType = null;
            Integer activityId = null;
            Boolean shared = null;
            BigDecimal subsidy = null;
            BigDecimal less = null;

            RunfastActivity businessActivity = null;
            if (object instanceof RunfastActivity) {
                businessActivity = (RunfastActivity) object;
                activityType = businessActivity.getPtype();
                activityId = businessActivity.getId();
                shared = businessActivity.getShared();
                subsidy = businessActivity.getAgent_subsidy() == null ? null : BigDecimal.valueOf(businessActivity.getAgent_subsidy());

            }
            if (object instanceof Map.Entry) {
                Map.Entry offActivityAmountPair = (Map.Entry) object;
                activityId = (Integer) offActivityAmountPair.getKey();
                Map<String, Object> offActivityMap = (Map<String, Object>) offActivityAmountPair.getValue();
                activityType = (Integer) offActivityMap.get("activityType");
                shared = (Boolean) offActivityMap.get("shared");
            }

            if (object instanceof RedPacketRecordWithOneRedActivityDto) {
                RedPacketRecordWithOneRedActivityDto activityDto = (RedPacketRecordWithOneRedActivityDto) object;
                RunfastActivity activity = activityDto.getActivity();
                activityId = activity.getId();
                activityType = activity.getPtype();
                shared = activity.getShared();
                subsidy = activity.getAgent_subsidy() == null ? null : BigDecimal.valueOf(activity.getAgent_subsidy());
            }

            RunfastOrderActivity orderActivity = new RunfastOrderActivity();
            orderActivity.setActivityId(activityId);
            orderActivity.setActivityType(activityType);
            orderActivity.setShared(shared);
            orderActivity.setSubsidy(subsidy == null ? null : subsidy.doubleValue());
            switch (activityType) {
                case 1:

                    RunfastFullLessExample fullLessExample = new RunfastFullLessExample();
                    fullLessExample.or().andActivity_idEqualTo(activityId);
                    fullLessExample.setOrderByClause("full desc");//按照full降序

                    List<RunfastFullLess> fullLessList = fullLessService.selectByExampleWithPageable(fullLessExample, PageRequest.of(0, 5));//只取5个
                    for (RunfastFullLess fullLess : fullLessList) {
                        BigDecimal full = fullLess.getFull() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fullLess.getFull());
                        less = fullLess.getLess() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fullLess.getLess());
                        int compareTo = cartPrice.compareTo(full);
                        if (compareTo == 1 || compareTo == 0) {

                            shareOffAmount = shareOffAmount.add(less);

                            orderActivity.setLess(less.doubleValue());

                            sharedValidActivityList.add(orderActivity);
                            break;
                        }

                    }

                    break;

                case 2://打折
                case 4://特价
                    Map.Entry offActivityAmountPair = (Map.Entry) object;
                    activityId = (Integer) offActivityAmountPair.getKey();
                    Map<String, Object> offActivityMap = (Map<String, Object>) offActivityAmountPair.getValue();
                    less = (BigDecimal) offActivityMap.get("offAmount");
                    less = less == null ? BigDecimal.valueOf(0) : less;
                    shareOffAmount = shareOffAmount.add(less);
                    orderActivity.setLess(less.doubleValue());
                    sharedValidActivityList.add(orderActivity);
                    break;
                case 5: {//全免配送费
                    Double fulls = businessActivity.getFulls();
                    BigDecimal full = fulls == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fulls);
                    int compareTo = cartPrice.compareTo(full);
                    if (compareTo == 1 || compareTo == 0) {
                        shareOffAmount = shareOffAmount.add(deliveryFee);
                        orderActivity.setLess(deliveryFee.doubleValue());
                        sharedValidActivityList.add(orderActivity);
                    }

                    break;
                }
                case 7: {//免部分配送费
                    Double fulls = businessActivity.getFulls();
                    BigDecimal full = fulls == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fulls);
                    int compareTo = cartPrice.compareTo(full);
                    if (compareTo == 1 || compareTo == 0) {
                        less = businessActivity.getLesss() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(businessActivity.getLesss());
                        if (less.compareTo(deliveryFee) == 1) less = deliveryFee;
                        shareOffAmount = shareOffAmount.add(less);
                        orderActivity.setLess(less.doubleValue());
                        sharedValidActivityList.add(orderActivity);
                    }


                    break;
                }
                case 8://新用户活动
                    RunfastGoodsSellRecordExample goodsSellRecordExample = new RunfastGoodsSellRecordExample();
                    goodsSellRecordExample.or().andUserIdEqualTo(userId).andAgentIdEqualTo(agentId);//代理商范围该用户是否下过单
                    List<RunfastGoodsSellRecord> goodsSellRecords = orderService.selectByExample(goodsSellRecordExample);
                    if (goodsSellRecords.isEmpty()) {//新用户下单
                        less = businessActivity.getLesss() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(businessActivity.getLesss());
//                        if(less >cartPrice)less = cartPrice;
                        shareOffAmount = shareOffAmount.add(less);
                        orderActivity.setLess(less.doubleValue());
                        sharedValidActivityList.add(orderActivity);
                    }
                    break;
                case 9:

                    break;
                case 10://商家红包
                case 11://返红包
                case 12://代理商红包
                    RedPacketRecordWithOneRedActivityDto activityDto = (RedPacketRecordWithOneRedActivityDto) object;
                    less = activityDto.getLess() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(activityDto.getLess());
//                    if(less >cartPrice)less = cartPrice;
                    shareOffAmount = shareOffAmount.add(less);
                    orderActivity.setLess(activityDto.getLess());
                    sharedValidActivityList.add(orderActivity);
                    break;

            }


        }

        map.put("sharedOffAmount", shareOffAmount);
        map.put("sharedValidActivityList", sharedValidActivityList);
        return map;
    }


    private Map<String, Object> getNotSharedMap(Integer userId, Integer agentId, BigDecimal cartPrice, BigDecimal deliveryFee, List<Object> notSharedActivityList) {
        BigDecimal notShareOffAmount = BigDecimal.valueOf(0); //不同享活动优惠金额（不同享活动由于互斥，只有一个活动参与最大优惠力度计算）

        Map<String, Object> map = new HashMap<>();
        RunfastOrderActivity notSharedValidActivity = null;//不同享活动列表中优惠力度最大的活动

        for (Object object : notSharedActivityList) {
            //  活动类型：1满减  2打折3赠品4特价5满减免运费6优惠券7免部分配送费8新用户立减活动9首单立减活动10商户红包11下单返红包,(新用户立减即首单立减)

            Integer activityType = null;
            Integer activityId = null;
            Boolean shared = null;
            BigDecimal subsidy = null;
            BigDecimal less = null;

            RunfastActivity businessActivity = null;
            if (object instanceof RunfastActivity) {
                businessActivity = (RunfastActivity) object;
                activityType = businessActivity.getPtype();
                activityId = businessActivity.getId();
                shared = businessActivity.getShared();
                subsidy = businessActivity.getAgent_subsidy() == null ? null : BigDecimal.valueOf(businessActivity.getAgent_subsidy());

            }
            if (object instanceof Map.Entry) {
                Map.Entry offActivityAmountPair = (Map.Entry) object;
                activityId = (Integer) offActivityAmountPair.getKey();
                Map<String, Object> offActivityMap = (Map<String, Object>) offActivityAmountPair.getValue();
                activityType = (Integer) offActivityMap.get("activityType");
                shared = (Boolean) offActivityMap.get("shared");
            }

            if (object instanceof RedPacketRecordWithOneRedActivityDto) {
                RedPacketRecordWithOneRedActivityDto activityDto = (RedPacketRecordWithOneRedActivityDto) object;
                RunfastActivity activity = activityDto.getActivity();
                activityId = activity.getId();
                activityType = activity.getType();
                shared = activity.getShared();
                subsidy = activity.getAgent_subsidy() == null ? null : BigDecimal.valueOf(activity.getAgent_subsidy());
            }

            RunfastOrderActivity orderActivity = new RunfastOrderActivity();
            orderActivity.setActivityId(activityId);
            orderActivity.setActivityType(activityType);
            orderActivity.setShared(shared);
            orderActivity.setSubsidy(subsidy == null ? null : subsidy.doubleValue());
            switch (activityType) {
                case 1:

                    RunfastFullLessExample fullLessExample = new RunfastFullLessExample();
                    fullLessExample.or().andActivity_idEqualTo(activityId);
                    fullLessExample.setOrderByClause("full desc");//按照full降序

                    List<RunfastFullLess> fullLessList = fullLessService.selectByExampleWithPageable(fullLessExample, PageRequest.of(0, 5));//只取5个
                    for (RunfastFullLess fullLess : fullLessList) {
                        BigDecimal full = fullLess.getFull() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fullLess.getFull());
                        less = fullLess.getLess() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fullLess.getLess());
                        int i = cartPrice.compareTo(full);
                        if (i == 1 || i == 0) {

                            if(notShareOffAmount.compareTo(less)<0){
                                notShareOffAmount = less;
                                orderActivity.setLess(less.doubleValue());
                                notSharedValidActivity = orderActivity;
                            }

                            break;
                        }

                    }

                    break;

                case 2://打折
                case 4://特价
                    Map.Entry offActivityAmountPair = (Map.Entry) object;
                    activityId = (Integer) offActivityAmountPair.getKey();
                    Map<String, Object> offActivityMap = (Map<String, Object>) offActivityAmountPair.getValue();
                    less = (BigDecimal) offActivityMap.get("offAmount");

                    less = less == null ? BigDecimal.valueOf(0) : less;
                    if(notShareOffAmount.compareTo(less)<0) {
                        notShareOffAmount = less;
                        orderActivity.setLess(less.doubleValue());
                        notSharedValidActivity = orderActivity;
                    }
                    break;
                case 5: {//全免配送费
                    Double fulls = businessActivity.getFulls();
                    BigDecimal full = fulls == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fulls);
                    int compareTo = cartPrice.compareTo(full);
                    if (compareTo == 1 || compareTo == 0) {
                        less = deliveryFee;
                        if (notShareOffAmount.compareTo(less) < 0) {
                            notShareOffAmount = deliveryFee;
                            orderActivity.setLess(deliveryFee.doubleValue());
                            notSharedValidActivity = orderActivity;
                        }
                    }
                    break;
                }
                case 7: {//免部分配送费
                    Double fulls = businessActivity.getFulls();
                    BigDecimal full = fulls == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(fulls);
                    int compareTo = cartPrice.compareTo(full);
                    if (compareTo == 1 || compareTo == 0) {
                        less = businessActivity.getLesss() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(businessActivity.getLesss());
                        if (less.compareTo(deliveryFee) == 1) less = deliveryFee;
                        if (notShareOffAmount.compareTo(less) < 0) {
                            notShareOffAmount = less;
                            orderActivity.setLess(less.doubleValue());
                            notSharedValidActivity = orderActivity;
                        }
                    }

                    break;
                }
                case 8://新用户活动
                    RunfastGoodsSellRecordExample goodsSellRecordExample = new RunfastGoodsSellRecordExample();
                    goodsSellRecordExample.or().andUserIdEqualTo(userId).andAgentIdEqualTo(agentId);//代理商范围该用户是否下过单
                    List<RunfastGoodsSellRecord> goodsSellRecords = orderService.selectByExample(goodsSellRecordExample);
                    if (goodsSellRecords.isEmpty()) {//新用户下单
                        less = businessActivity.getLesss() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(businessActivity.getLesss());
//                        if(less> cartPrice) less = cartPrice;
                        if(notShareOffAmount.compareTo(less)<0) {
                            notShareOffAmount = less;
                            orderActivity.setLess(less.doubleValue());
                            notSharedValidActivity = orderActivity;
                        }
                    }
                    break;
                case 9:
                    break;
                case 10://商家红包
                case 11://返红包
                    RedPacketRecordWithOneRedActivityDto activityDto = (RedPacketRecordWithOneRedActivityDto) object;
                    less = activityDto.getLess() == null ? BigDecimal.valueOf(0) : BigDecimal.valueOf(activityDto.getLess());
                    if(notShareOffAmount.compareTo(less)<0) {
                        notShareOffAmount = notShareOffAmount.add(less);
                        orderActivity.setLess(less.doubleValue());
                        notSharedValidActivity = orderActivity;
                    }
                    break;

            }


        }

        List<Object> notSharedValidActivityList = new ArrayList<>();
        if (notSharedValidActivity != null) notSharedValidActivityList.add(notSharedValidActivity);
        map.put("notSharedOffAmount", notShareOffAmount);
        map.put("notSharedValidActivityList", notSharedValidActivityList);
        return map;
    }


    @Override
    public Result recur(Integer userId, Integer orderId) {
        RunfastGoodsSellRecord order = orderService.selectByPrimaryKey(orderId);
        Integer businessId = order.getBusinessId();
        if (order == null) return Result.fail(ResultCode.ORDER_NOT_EXIST);

        List<CartItem> cartItemList = new ArrayList<>();

        RunfastGoodsSellChildrenExample goodsSellChildrenExample = new RunfastGoodsSellChildrenExample();
        goodsSellChildrenExample.or().andPidEqualTo(orderId).andOrderCodeEqualTo(order.getOrderCode());
        List<RunfastGoodsSellChildren> goodsSellChildren = goodsSellChildrenService.selectByExample(goodsSellChildrenExample);

        for (RunfastGoodsSellChildren goodsSellChild : goodsSellChildren) {

            CartItem cartItem = new CartItem();

            CartItemKey cartItemKey = new CartItemKey();
            cartItemKey.setGoodsId(goodsSellChild.getGoodsSellId());
            cartItemKey.setStandarId(goodsSellChild.getGoodsSellStandardId());

            List<OptionIdPair> optionIdPairList = new ArrayList<>();

            String optionIds = goodsSellChild.getOptionIds();
            if (StringUtils.isNotBlank(optionIds)) {
                String[] split = optionIds.split(",");
                for (String s : split) {
                    if (StringUtils.isNotBlank(s)) {
                        Integer subOptionId = Integer.valueOf(s);
                        RunfastGoodsSellSubOption goodsSellSubOption = subOptionService.selectByPrimaryKey(subOptionId);
                        Integer optionId = goodsSellSubOption.getOptionId();
                        OptionIdPair optionIdPair = new OptionIdPair();
                        optionIdPair.setOptionId(optionId);
                        optionIdPair.setSubOptionId(subOptionId);

                        optionIdPairList.add(optionIdPair);

                    }

                }
            }
//
            cartItemKey.setOptionIdPairList(optionIdPairList);
            cartItem.setKey(cartItemKey);


            cartItem.setStandarOptionName(goodsSellChild.getStandarOptionName());
            cartItem.setNum(goodsSellChild.getNum());
            cartItem.setChecked(true);
            cartItemList.add(cartItem);
        }


        //更新至redis
        Cart redisCart = new Cart();
        redisCart.setCartItems(cartItemList);

        cartDetail(businessId, redisCart, userId,null);

        /**
         * 覆盖当前的购物车
         */
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put(Constants.REDIS_NAMESPACE_CART + userId, businessId, redisCart);
        return Result.ok("", redisCart);
    }

    @Override
    public Result chooseCartItem(Integer businessId, List<CartItem> cartItems, Integer userId) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        Cart redisCart = (Cart) hashOperations.get(Constants.REDIS_NAMESPACE_CART + userId, businessId);
        if (redisCart == null) return Result.fail(ResultCode.FAIL, "购物车为空，请先添加购物车");
        List<CartItem> cartItemList = redisCart.getCartItems();
        if (cartItemList == null || cartItemList.isEmpty()) {
            return Result.fail(ResultCode.FAIL, "购物车为空，请先添加购物车");
        } else {

            for (CartItem item : cartItemList) item.setChecked(false);

            for (CartItem cartItem : cartItems) {
                CartItemKey key = cartItem.getKey();
                CartItem redisCartItem = null;
                for (CartItem item : cartItemList) {
                    if (key != null && key.equals(item.getKey())) {
                        redisCartItem = item;
                        redisCartItem.setChecked(true);
                        break;
                    }

                }

                if (redisCartItem == null) return Result.fail(ResultCode.FAIL, "购物车中不存在该购物信息");
            }

        }

        cartDetail(businessId, redisCart, userId, null);
        //更新至redis
        hashOperations.put(Constants.REDIS_NAMESPACE_CART + userId, businessId, redisCart);

        //返回当前购物车
        return Result.ok("", redisCart);
    }
}
